#pragma once
#include <stdlib.h>
#include <GL/glut.h>
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <vector>

#include "Tile.h"
#include "LightRubble.h"
#include "MediumRubble.h"
#include "PlatformDelimiter.h" 
#include "LargeRubble.h"
#include "MiddlePit.h"
#include "EndPit.h"
#include "skyBox.h"
#include "HomeBase.h"
#include "lightPost.h"
#include "BlockPart.h"
#include "HoleBlock.h"
#include "ShortHoleBlock.h"
#include "IntermediateBase.h"
#include <string>

struct Element{
	int ID;
	/*GLfloat x;
	GLfloat z;*/
	GLfloat y;
	GLfloat height;
};

class Map
{
public:
	Map(std::string);			//default size 50x50 units
	~Map(void);
	void Map::loadMapFromFile(std::string source);
	void Map::makeDisplayList();
	int move(GLfloat, GLfloat, GLfloat, GLfloat = -1, GLfloat = -1, GLfloat = -1);
	int moveControlUnit(GLfloat, GLfloat, GLfloat);
	void display();	
	void setLocation(int, GLfloat, GLfloat, GLfloat, GLfloat);
	void removeObject(GLfloat, GLfloat);
	GLint getWidth();
	GLint getLength();
	GLint getSkyBoxSize();

	// lightPosts
	lightPost* lightPostNW;
	lightPost* lightPostNE;
	lightPost* lightPostSW;
	lightPost* lightPostSE;

private:
	void initArrays();
	void setMapFixedObject();
	void addIDmovableObject(int);
	void removeIDmovableObject(int);
	int checkInMovableObject(GLfloat, GLfloat, GLfloat, GLfloat = -1, GLfloat = -1, GLfloat = -1);
	int checkInFixedObject(GLfloat, GLfloat, GLfloat);

	int width;									// along x-axis
	int length;									// along z-axis

	GLuint DLindex;								// display list index
	std::vector<std::vector<char>> mapArray;	// for the array-based map definition
	std::vector<std::vector<Element*>> movableArray;
	/*** ID in Fixed Array ***
	ids for fixed objects are <0 to be able
	to differentiate them form ids robots
		delimiter = -1
		rubble = -2
		medium pit = -3
		ending pit = -4
		construction block = -5
		base = -6
	*************************/
	std::vector<std::vector<Element*>> fixedArray;
	std::vector<int> IDmovableObjects;

	// elements
	Tile* regularTile;
	MediumRubble* mRubble;
	LightRubble* lRubble;
	LargeRubble* largeRubble;
	MiddlePit* midPit;
	EndPit* endPit;
	PlatformDelimiter* delimiter;
	skyBox* skybox;

	HomeBase* homebase;
	HomeBase* enemyBase;

	IntermediateBase* nuclearFactory;
	IntermediateBase* missileFactory;
	IntermediateBase* cannonFactory;
	IntermediateBase* eBrainFactory;
	IntermediateBase* phaserFactory;

	PlainBlock* constBlock;
	PlainShortBlock* constBlockShort;

	HoleBlock* holeBlock;
	ShortHoleBlock* holeBlockShort;

	// position of bases
	GLfloat homeBaseX;
	GLfloat homeBaseZ;
	GLfloat enemyBaseX;
	GLfloat enemyBaseZ;
	GLfloat nuclearFactoryX;
	GLfloat nuclearFactoryZ;
	GLfloat missileFactoryX;
	GLfloat missileFactoryZ;
	GLfloat cannonFactoryX;
	GLfloat cannonFactoryZ;
	GLfloat eBrainFactoryX;
	GLfloat eBrainFactoryZ;
	GLfloat phaserFactoryX;
	GLfloat phaserFactoryZ;
};

